#include <sobjc-commons/defines.h>
#include "sobjc-commons/builtin_sels.h"

#define OBJC_NUM_BUILTIN_SELS   27

struct objc_builtin_selector
objc_builtin_selectors[OBJC_NUM_BUILTIN_SELS] = {
  {"alloc", 0, 0},
  {"class", 0, 0},
  {"conformsToProtocol:", 1, 0},
  {"copy", 0, 0},
  {"doesNotRecognizeSelector:", 1, 0},
  {"free", 0, 0},
  {"hash", 0, 0},
  {"init", 0, 0},
  {"initialize", 0, 0},
  {"instanceMethodForSelector:", 1, 0},
  {"instancesRespondToSelector:", 1, 0},
  {"isEqual:", 1, 0},
  {"isKindOfClass:", 1, 0},
  {"isMemberOfClass:", 1, 0},
  {"methodForSelector:", 1, 0},
  {"name", 0, 0},
  {"new", 0, 0},
  {"notImplementedSelector:", 1, 0},
  {"performSelector:", 1, 0},
  {"performSelector:withObject:", 2, 0},
  {"performSelector:withObject:withObject:", 3, 0},
  {"release", 0, 0},
  {"respondsToSelector:", 1, 0},
  {"retain", 0, 0},
  {"self", 0, 0},
  {"subclassResponsibilitySelector:", 1, 0},
  {"superclass", 0, 0}
};

struct objc_builtin_selector *
objc_get_builtin_sel(const char *name)
{
  int l, u, i;
  const char *t, *n;
  char c;

  c = *name;
  l = 0;
  u = OBJC_NUM_BUILTIN_SELS - 1;
loop:
  while (u - l > 1) {
    i = (u - l) / 2 + l;
    t = objc_builtin_selectors[i].name;
    if (c == *t) {
      n = name;
      while (*++t && *++n) {
        if (*n > *t) {
          l = i;
          goto loop;
        } else if (*n < *t) {
          u = i;
          goto loop;
        }
      }
      if (*t == *n)
        return &objc_builtin_selectors[i];
      else if (*t)
        u = i;
      else
        l = i;
    } else if (c > *t)
      l = i;
    else
      u = i;
  }

  if (STREQ(objc_builtin_selectors[u].name, name))
    return &objc_builtin_selectors[u];
  else if (STREQ(objc_builtin_selectors[l].name, name))
    return &objc_builtin_selectors[l];
  else
    return NULL;
}

